// 写一个类，专门用于提供 ip+端口 与 sockaddr_in之间的转换
#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "Common.hpp"

namespace wxd
{
    class InetAddrTrans
    {
    public:
        InetAddrTrans()
        {
        }
        // 构造函数-给出sockaddr_in构建ip+port
        // 用途：解析从网络中取到的地址信息
        // 网络->本机
        InetAddrTrans(const sockaddr_in &s_addr_in)
            : _s_addr_in(s_addr_in)
        {
            //_ip = inet_ntoa(_s_addr_in.sin_addr);
            char ipbuffer[64];
            inet_ntop(AF_INET,&s_addr_in.sin_addr,ipbuffer,sizeof(s_addr_in));

            _ip = ipbuffer;
            _port = ntohs(_s_addr_in.sin_port); // 把网络序列转成本机的
        }

        // 构造函数-给出指定ip+port构建sockaddr_in
        // 本机->网络
        InetAddrTrans(const std::string &ip, uint16_t port)
            : _ip(ip), _port(port)
        {
            // 填充sockaddr_in结构
            // 清空sockaddr_in
            memset(&_s_addr_in, 0, sizeof(_s_addr_in));
            _s_addr_in.sin_family = AF_INET;
            //_s_addr_in.sin_addr.s_addr = inet_addr(_ip.c_str());
            inet_pton(AF_INET,ip.c_str(),&_s_addr_in.sin_addr);
            _s_addr_in.sin_port = htons(_port);
        }

        // 构造函数-给出任意ip 指定port构建sockaddr_in
        // 本机->网络
        InetAddrTrans(uint16_t port)
            : _port(port),_ip("0")
        {
            // 填充sockaddr_in结构
            // 清空sockaddr_in
            memset(&_s_addr_in, 0, sizeof(_s_addr_in));
            _s_addr_in.sin_family = AF_INET;
            _s_addr_in.sin_addr.s_addr = INADDR_ANY;
            _s_addr_in.sin_port = htons(_port);
        }

        // InetAddrTrans(const InetAddrTrans& addr_trans) = default;
        // InetAddrTrans& operator=(const InetAddrTrans& addr_trans) = default;
        // 仿函数默认返回sockaddr_in
        sockaddr_in operator()()
        {
            return _s_addr_in;
        }

        std::string Ip()const
        {
            return _ip;
        }

        u_int16_t Port()const
        {
            return _port;
        }

        bool operator==(const InetAddrTrans &addr_trans) const
        {
            return (_ip == addr_trans._ip) && (_port == addr_trans._port);
        }

        //直接返回sockaddr*的方法
        sockaddr* SockaddrPtr()const
        {
            return ADDR_PTR(_s_addr_in);
        }
        //返回_s_addr_in长度的方法
        socklen_t SockLen()const
        {
            return sizeof(_s_addr_in);
        }
        //返回ip:port格式的字符串
        std::string AddrInfo()
        {
            return _ip+":"+std::to_string(_port);
        }

    private:
        u_int16_t _port;
        std::string _ip;
        struct sockaddr_in _s_addr_in;
    };
}
